#include "napi/native_api.h"
#include <js_native_api.h>
#include <js_native_api_types.h>

#include <string>

#define LOG_DOMAIN 0x1fff
#define LOG_TAG "jiangtao"
#include "hilog/log.h"

static napi_value Add(napi_env env, napi_callback_info info) {
    OH_LOG_ERROR(LogType::LOG_APP, "Add");
    size_t argc = 3;
    napi_value args[3] = {nullptr};
    napi_value context = nullptr;

    napi_get_cb_info(env, info, &argc, args, &context, nullptr);

    double value0;
    napi_get_value_double(env, args[0], &value0);

    double value1;
    napi_get_value_double(env, args[1], &value1);

    napi_value callbackArgs[1] = {nullptr};
    napi_create_double(env, value0 + value1, &callbackArgs[0]);
    napi_value res = nullptr;

    auto status = napi_call_function(env, context, args[2], 1, callbackArgs, &res);

    OH_LOG_ERROR(LogType::LOG_APP, "%s = %d", __FUNCTION__, (int32_t)status);

    return res;
}

// only for test, 记录用户输入
static std::string input_msg = "";

// js 函数回调，触发界面显示Dialog
static napi_ref callback = nullptr;

static napi_value Test(napi_env env, napi_callback_info info) {

    OH_LOG_ERROR(LogType::LOG_APP, "Test");

    napi_value argv[1];
    napi_create_string_utf8(env, input_msg.c_str(), NAPI_AUTO_LENGTH, &argv[0]);

    napi_value global;
    napi_get_global(env, &global);

    napi_value cb = nullptr;

    napi_get_reference_value(env, callback, &cb);

    napi_valuetype type;
    napi_typeof(env, cb, &type);
    OH_LOG_ERROR(LogType::LOG_APP, "%s = %d", __FUNCTION__, (int32_t)type);

    napi_value result = nullptr;
    napi_status status = napi_call_function(env, global, cb, 1, &argv[0], &result);

    OH_LOG_ERROR(LogType::LOG_APP, "%s = %d", __FUNCTION__, (int32_t)status);

    return result;
}

static napi_value SetIMGShowMethod(napi_env env, napi_callback_info info) {
    size_t argc = 1;
    napi_value args[1] = {nullptr};

    OH_LOG_ERROR(LogType::LOG_APP, "SetIMGShowMethod");

    auto status = napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    OH_LOG_ERROR(LogType::LOG_APP, "%s = %d", __FUNCTION__, (int32_t)argc, (int32_t)status);

    napi_create_reference(env, args[0], 1, &callback);

    return nullptr;
}

static napi_value SetInputMessage(napi_env env, napi_callback_info info) {
    size_t argc = 1;
    napi_value args[1] = {nullptr};

    OH_LOG_ERROR(LogType::LOG_APP, "SetInputMessage");

    napi_get_cb_info(env, info, &argc, args, nullptr, nullptr);

    char buf[1024] = {
        0,
    };
    size_t result = 0;

    napi_get_value_string_utf8(env, args[0], buf, 1024, &result);

    input_msg = std::string(buf);

    OH_LOG_ERROR(LogType::LOG_APP, "input_msg = %s", input_msg.c_str());

    return nullptr;
}

EXTERN_C_START
static napi_value Init(napi_env env, napi_value exports) {
    napi_property_descriptor desc[] = {
        {"add", nullptr, Add, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"test", nullptr, Test, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"setIMGShowMethod", nullptr, SetIMGShowMethod, nullptr, nullptr, nullptr, napi_default, nullptr},
        {"setInputMessage", nullptr, SetInputMessage, nullptr, nullptr, nullptr, napi_default, nullptr},
    };
    napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
    return exports;
}
EXTERN_C_END

static napi_module demoModule = {
    .nm_version = 1,
    .nm_flags = 0,
    .nm_filename = nullptr,
    .nm_register_func = Init,
    .nm_modname = "hello",
    .nm_priv = ((void *)0),
    .reserved = {0},
};

extern "C" __attribute__((constructor)) void RegisterHelloModule(void) {
    napi_module_register(&demoModule);
}
